home *** CD-ROM | disk | FTP | other *** search
- /*
- devlib: Header describing the format of the object file.
- Warning: changes to this file affect both the AS and the LINK applications.
-
- source: LIBofile.h
- started: May 9, 1994.
- version:
- February 3, 1995.
- Added comment nodes.
- Added f_area_comments field to areas.
- Removed f_ref_next field.
- Added LAST_REF bit and related macros.
- May 21, 1994.
- Added abbreviations for byte nodes.
- May 19, 1994.
- Added f_unit_name.
- May 13, 1994.
- Added f_area_index.
- May 12, 1994.
- Added f_area_name.
- Added fh_areas.
- May 11, 1994.
- Area nodes now contain reference lists.
- May 9, 1994.
- All flags are shared between in-memory and file versions.
- */
-
- #ifndef LIBofile_h_
- #define LIBofile_h_
-
- #pragma once
-
- /*
- Define abbreviations.
- */
-
- #define f_comment_ptr(p)((f_comment *) (p))
- #define f_header_ptr(p) ((f_header *) (p))
- #define f_ref_ptr(p) ((f_ref_node *) (p))
- #define f_tail_ptr(p) ((f_trailer *) (p))
-
- /*
- Define the typedefs of the object file.
-
- An offset is the number of bytes from the start of an object file.
- Offsets are converted to pointers by the fscan routines.
- A zero offset represents a NULL pointer.
-
- An index is a position relative to some (understood) data structure.
- Zero is *not* a valid index and represents an end-of-list.
- */
-
- typedef ulong f_offset;
- typedef ulong f_index;
- typedef struct f_area_node_struct f_area_node;
- typedef struct f_comment_struct f_comment;
- typedef struct f_dict_node_struct f_dict_node;
- typedef struct f_header_struct f_header;
- typedef struct f_ref_node_struct f_ref_node;
- typedef struct f_trailer_struct f_trailer;
- typedef struct f_unit_node_struct f_unit_node;
-
- /*
- An area consists of an ordered sequence of bits, specified by a byte list.
- 2/3/95: added f_area_comments field.
- */
-
- static struct f_area_node_struct {
- f_index f_area_index; /* The file index. */
- ulong f_area_app_length; /* Size of the area in the application. */
- ulong f_area_file_length; /* Unpadded size of the area in the object file. */
- f_offset f_area_refs; /* The references from within this area. */
- f_offset f_area_bytes; /* The "byte list" of the area. */
- f_offset f_area_comments; /* The comment list. */
- f_index f_area_name; /* The dictionary index of the area's name. */
- };
-
- /*
- The byte list represents the bytes of an area.
-
- I'm unsure about whether to use a byte list,
- so the byte list is used only if USE_BYTE_LIST is #defined.
- The byte list handles larege DCB instructions more efficiently
- and also allows the linker more flexibility in alignment.
-
- fill nodes are generated from DCB instructions.
- align nodes are generated from ALIGN instructions.
- byte nodes are generated from all other cnodes.
- byte nodes are followed by the indicated number of bytes.
- */
-
- #undef USE_BYTE_LIST
- #define USE_BYTE_LIST
-
- #ifdef USE_BYTE_LIST
-
- /* Abbreviations. */
- #define f_align_ptr(p) ((f_align_node *) (p))
- #define f_byte_ptr(p) ((f_byte_node *) (p))
- #define f_fill_ptr(p) ((f_fill_node *) (p))
-
- /* Define the type codes in byte nodes. */
- enum { F_BAD_TYPE, F_ALIGN_TYPE, F_BYTE_TYPE, F_FILL_TYPE };
-
- typedef struct f_align_node_struct f_align_node;
- typedef struct f_byte_node_struct f_byte_node;
- typedef struct f_fill_node_struct f_fill_node;
-
- #define BYTE_NODE_HEAD\
- short f_byte_type;\
- f_offset f_byte_next
-
- static struct f_align_node_struct {
- BYTE_NODE_HEAD;
- short f_align_pad;
- };
-
- static struct f_byte_node_struct {
- BYTE_NODE_HEAD;
- ulong f_byte_size;
- };
-
- static struct f_fill_node_struct {
- BYTE_NODE_HEAD;
- ulong f_fill_count;
- long f_fill_val;
- };
- #endif
-
- /*
- The comment list contains all line and stack comments for an area.
- The list is terminated with a node with a zero comment_kind.
- */
- static struct f_comment_struct {
- short f_comment_kind; /* C_xxx_COMMENT: see below. */
- ulong f_comment_offset; /* Stack offset (location counter for line comments) */
- ulong f_comment_size; /* Size of variable (not used for line comments) */
- };
-
- /* Define the possible values of f_comment_kind and comment_kind fields (AScnodes.h). */
- enum {
- C_BAD_COMMENT = 0,
- C_AUTO_COMMENT,
- C_BIG_TEMP_COMMENT,
- C_FORMAL_COMMENT,
- C_FTEMP_COMMENT,
- C_HIDDEN_PTR_COMMENT,
- C_LINE_COMMENT,
- C_BAD_LAST_COMMENT
- };
-
- /*
- The symbol dictionary contains one entry for each symbol defined or
- referenced in the object file.
- Each f_dict node is followed by the padded name of the symbol.
- */
-
- static struct f_dict_node_struct {
-
- f_index f_dict_area; /* The area in which the label is defined, or 0. */
- f_offset f_dict_offset; /* Offset of the symbol from the start of the unit. */
- short f_dict_length; /* The length of the *unpadded* symbol */
-
- /* Dictionary flags are the same whether on disk or in memory. */
-
- short dict_flags; /* Various flags defined below. */
- };
-
- /* Define operations on the dict_flag fields. */
-
- enum {
- DEF_DFLAG = 0x01, /* 1: the label is defined in this file. */
- GLOBAL_DFLAG = 0x02, /* 1: the label is known outside this file. */
- IMPORT_DFLAG = 0x04, /* 1: the label is imported from another file. */
- REF_DFLAG = 0x08 /* 1: the label is referenced in this file. */
- };
-
- #define dict_is_defined(i) ((((i) -> dict_flags) & DEF_DFLAG) != 0)
- #define dict_is_global(i) ((((i) -> dict_flags) & GLOBAL_DFLAG) != 0)
- #define dict_is_imported(i) ((((i) -> dict_flags) & IMPORT_DFLAG) != 0)
- #define dict_is_referenced(i) ((((i) -> dict_flags) & REF_DFLAG) != 0)
-
- #define dict_set_defined(i) {(i) -> dict_flags |= DEF_DFLAG;}
- #define dict_set_global(i) {(i) -> dict_flags |= GLOBAL_DFLAG;}
- #define dict_set_import(i) {(i) -> dict_flags |= IMPORT_DFLAG;}
- #define dict_set_referenced(i) {(i) -> dict_flags |= REF_DFLAG;}
-
- /*
- Object files start with a header.
-
- The version and revision fields must exist in all object files.
- The item field allows object files to have zero items.
- The value of magic must match value in the end field in the trailer.
-
- Headers, f_items and trailers are padded to a LINKER_PADDING boundary
- using the padding macro defined below.
- */
-
- #define LINK_VERSION 1 /* Development versions are less than 100. */
- #define LINK_REVISION 2
- #define MAX_REVISION 100
- #define LINK_MAGIC 0x1234
-
- #define LINKER_PADDING 2
- #define padding(size) (size + ((LINKER_PADDING - (size % LINKER_PADDING)) % LINKER_PADDING))
-
- static struct f_header_struct { /* Disk format... */
-
- unsigned short fh_version; /* Version of the object file format. */
- unsigned short fh_revision; /* Sub-version of the object file format. */
- ulong fh_magic; /* Consistency check. */
- ulong fh_reserved1; /* Reserved for future use. */
- ulong fh_reserved2; /* Reserved for future use. */
- ulong fh_symbols; /* The number of symbols in the symbol dictionary. */
- ulong fh_units; /* The number of units in the file. */
- ulong fh_areas; /* The number of areas in the file. */
- f_offset fh_dictionary; /* Offset of the symbol dictionary or 0 if none. */
- f_offset fh_unit; /* Offset of the first unit or 0 if none. */
- };
-
- /*
- Each area contains a list of references contained within the area.
- This list is used by the linker in two ways:
- 1) To determine what areas (hense what units) to link into the application.
- 2) To patch fields within included areas.
-
- Associating ref nodes with areas instead of units allows
- the linker to allocate code and data areas independently.
-
- Reference nodes represent a reference to an atom of the indicated size.
-
- WARNING:
- We could get rid of the f_ref_next field by using a flag bit.
- That would *not* be a good idea.
- Although the f_ref_next wastes space in the .o file,
- it *saves* main memory in the liner because the linker converts
- f_ref_nodes to in-memory nodes in place!
- */
-
- static struct f_ref_node_struct {
-
- f_offset f_ref_next; /* Next node on the reference list. */
- f_index f_ref_dict; /* Index of the label being referenced. */
- ulong f_ref_offset; /* Bytes from start of area of the field to be patched. */
- short f_ref_size; /* The size of the field to be patched, in bytes. */
-
- /* Reference flags are the same whether on disk or in memory. */
-
- short ref_flags; /* Attribute bits: see below */
- };
-
- /* Define bits in the ref_flags field. */
-
- #define NEG_RFLAG 0x01
- #define ref_set_neg(i) {(i) -> ref_flags |= NEG_RFLAG;}
- #define ref_is_neg(i) ((((i) -> ref_flags) & NEG_RFLAG) != 0)
-
- #if 0 /* Use a NULL f_ref_next field, not flag bits, to end the reference list! */
- #define LAST_RFLAG 0x02
- #define ref_set_last(i) {(i) -> ref_flags |= LAST_RFLAG;}
- #define ref_is_last(i) ((((i) -> ref_flags) & LAST_RFLAG) != 0)
- #endif
-
- /*
- The trailer field follows the last file item node.
- This field exists solely as a consistency check on the file.
-
- The assembler pads the file as necessary so that the trailer
- starts on a LINKER_PADDING byte boundary.
- */
-
- static struct f_trailer_struct {
- ulong t_file_size; /* The file size, including the trailer. */
- ulong t_end; /* Value of t_end must match value in h_magic. */
- };
-
- /*
- A unit is the smallest element that can be included or excluded from an
- application by the linker.
- */
-
- static struct f_unit_node_struct {
-
- f_offset f_unit_next; /* Offset of the next unit */
- f_offset f_unit_code_area; /* Offset of the unit's code area. */
- f_offset f_unit_data_area; /* Offset of the unit's data area. */
- f_index f_unit_name; /* The dictionary index of the unit's name. */
-
- /* Unit flags are the same whether on disk or in memory. */
-
- short unit_flags; /* Various flags defined below. */
- };
-
- /*
- Define abbreviations for operations on the m_unit_flag fields.
-
- The SCAN_UFLAG field is used only by the linker.
- */
- enum {
- PROC_UFLAG = 0x01, /* TRUE: the unit is a PROC unit. */
- RECORD_UFLAG = 0x02, /* TRUE: the unit is a RECORD unit. */
- SCAN_UFLAG = 0x04 /* TRUE: the unit is on the scan list. */
- };
-
- #define unit_is_on_scan_list(i) ((((i) -> unit_flags) & SCAN_UFLAG) != 0)
- #define unit_is_proc(i) ((((i) -> unit_flags) & PROC_UFLAG) != 0)
- #define unit_is_record(i) ((((i) -> unit_flags) & RECORD_UFLAG) != 0)
-
- #define unit_set_on_scan_list(i) { (i) -> unit_flags |= SCAN_UFLAG; }
- #define unit_set_proc(i) { (i) -> unit_flags |= PROC_UFLAG; }
- #define unit_set_record(i) { (i) -> unit_flags |= RECORD_UFLAG;}
-
- #endif /* LIBofile_h_ */
-